/*
 * common.c
 *
 *  Created on: Nov 5, 2016
 *      Author: root
 */

#include <memory.h>
#include "common.h"
#include "aopengine.h"
#include "fpengine.h"
#include "lexerengine.h"
#include "loaderengine.h"
#include "logicengine.h"
#include "oopengine.h"
#include "pmengine.h"
#include "../trans/parser.h"
#include "../trans/matcher.h"
#include "refactorengine.h"

void init_macro_functions(Funny *globalFunny) {
    hashmap_put(globalFunny->macros, "EXTRACT", extract);
	hashmap_put(globalFunny->macros, "ARGLIST", arglist);
    hashmap_put(globalFunny->macros, "TARGET", target);
    hashmap_put(globalFunny->macros, "FUNCNAME", funcname);
	hashmap_put(globalFunny->macros, "MATCH", match);

    hashmap_put(globalFunny->macros, "LOADTPL", loadtemplate);
    hashmap_put(globalFunny->macros, "LOADFILE", loadfile);
    hashmap_put(globalFunny->macros, "LOADPKG", loadpackage);

    hashmap_put(globalFunny->macros, "LEX", lex);
    hashmap_put(globalFunny->macros, "RULE", rule);
    hashmap_put(globalFunny->macros, "GROUP", group);
    hashmap_put(globalFunny->macros, "TOKEN", token);

	hashmap_put(globalFunny->macros, "DEFCLASS", defclass);
	hashmap_put(globalFunny->macros, "METHODNAME", methodname);
    hashmap_put(globalFunny->macros, "DEFMETHOD", defmethod);
    hashmap_put(globalFunny->macros, "NEWINSTANCE", newinstance);
    hashmap_put(globalFunny->macros, "SENDMSG", sendmsg);
    hashmap_put(globalFunny->macros, "GETPROP", getprop);
    hashmap_put(globalFunny->macros, "SETPROP", setprop);

    hashmap_put(globalFunny->macros, "DEFASPECT", defaspect);
    hashmap_put(globalFunny->macros, "EXECADV", execadv);

    hashmap_put(globalFunny->macros, "DEFASPECT", defaspect);
    hashmap_put(globalFunny->macros, "EXECADV", execadv);

    hashmap_put(globalFunny->macros, "DEFFACT", deffact);
    hashmap_put(globalFunny->macros, "DEFRULE", defrule);
    hashmap_put(globalFunny->macros, "ANSWER", answer);

    hashmap_put(globalFunny->macros, "DEFPAT", defpat);
    hashmap_put(globalFunny->macros, "MATCHPAT", matchpat);

	//hashmap_put(globalFunny->macros, "ADDMETHOD", addmethod);
	hashmap_put(globalFunny->macros, "HIERARCHY", hierarchy);
	//hashmap_put(globalFunny->macros, "TRANSLATE", translate);
	//hashmap_put(globalFunny->macros, "PUBLISH", publish);
    hashmap_put(globalFunny->macros, "DEFCOMP", defcomp);
    hashmap_put(globalFunny->macros, "REQUIRE", require);

    hashmap_put(globalFunny->macros, "DUMPCODE", dumpcode);
    hashmap_put(globalFunny->macros, "DUMPCLASS", dumpclass);
    hashmap_put(globalFunny->macros, "DUMPHIER", dumphier);
}


void generate_code() {
    //Tree* inheritanceTree = globalFunny->inheritance;
    //generate_class_code(inheritanceTree->root);

    QueueNode *node = globalFunny->modules->head;
    while (node != NULL) {
        ModuleMeta *module = (ModuleMeta *)(node->element);
        String moduleName = module->moduleName;
        String modulePath = module->modulePath;
        String sourceFileName = concatenate(moduleName, FUNNY_FILE_EXTENSION);
        String targetFileName = concatenate(moduleName, SCHEME_FILE_EXTENSION);
        String source = append_path(modulePath, sourceFileName);
        String target = append_path(modulePath, targetFileName);
        read_write_file_with_data(source, target, module, generate_scheme_code);
        node = node->next;
    }
}

void* generate_scheme_code(FILE *in, FILE *out, void* module) {
    ModuleMeta *moduleMeta = (ModuleMeta *) module;
    Statement *s = NULL;
    while (has_next_statement(in)) {
        s = next_statement(in);
        String r = match_internal(s);
        if (r != NULL) {
            fprintf(out, "%s\n", r);
        }
    }
    return NULL;
}


